'''
Created on Oct 19, 2012

@author: Artur
'''
import utils

def Blocking():
    width = 15
    data = utils.ParseInstance('C:/workspace/pceps/data/data_2000_dirty')
    (attrs, head_str) = utils.ParseSchema('C:/workspace/FD_Repair/test/uis/schema', width)
    fds = utils.ParseFds('C:/workspace/FD_Repair/test/uis/fds_old', attrs)
    
    
    bid = 0
    # cell : (tupleid, attrid)
    bmap = {} # block map: bid -> cell[]
    bmap[0] = []
    cmap = {} # cell map: cell -> bid
    
    
    def RecurseMerge(fd, i, j, fd_list):
        for loop_fd in fd_list:
            # rhs of fd is in lhs of loop_fd
            if fd[1] in loop_fd[0]:
                Merge(loop_fd, i, j, fd_list)
    
    
    def Merge(fd, i, j, fd_list):
        nonlocal bid, bmap, cmap
        
        # lhs values are equal
        for a in fd[0]:
            if data[i][a] != data[j][a]:
                return
        
        # merge lhs and rhs cells
        for a in list(fd[0]) + [fd[1],]:
            c1 = (i, a)
            c2 = (j, a)
            for c in [c1, c2]:
                if c not in cmap:
                    bmap[bid].append(c)
                    cmap[c] = bid
                else:
                    old_bid = cmap[c]
                    if old_bid != bid:
                        bmap[bid] += bmap[old_bid]
                        for cell in bmap[old_bid]:
                            cmap[cell] = bid
                        del bmap[old_bid]
                    
        
        bid += 1
        bmap[bid] = []
        
        
        fd_list.remove(fd);
        RecurseMerge(fd, i, j, fd_list)
        
        
    def PartitionBlocks():
        for i in range(len(data) - 1):
            for j in range(i + 1, len(data)):
                for fd in fds:
                    fd_list = list(fds)
                    Merge(fd, i, j, fd_list)
                    
                    
                    
    PartitionBlocks()
    del bmap[bid] # delete last entry - it is empty
    print('#blocks: {}'.format(len(bmap)))
    utils.PrintoutBlockMap(bmap, 'out_new.txt', data, width, head_str, len(attrs))
    
    with open('out_new_raw.txt', 'w') as f:
        for bid in bmap.keys():
            f.write('{}: '.format(bid))
            for cell in bmap[bid]:
                f.write('[{}, {}], '.format(cell[0], cell[1]))
            f.write('\n')



def test1():
    bmap = utils.ParseBlockMap('out_new_raw.txt')
    (bmap2, cmap2) = utils.ParseBlockAndCellMap('C:/workspace/pceps/out.txt')
    for key in bmap.keys():
        contains = False
        for key2 in bmap2.keys():
            if set(bmap[key]) == set(bmap2[key2]):
                contains = True
                break
        if not contains:
            print('Block {} in new is NOT in old'.format(key))
    for key2 in bmap2.keys():
        contains = False
        for key in bmap.keys():
            if set(bmap[key]) == set(bmap2[key2]):
                contains = True
                break
        if not contains:
            print('Block {} in old is NOT in new'.format(key))
    
    
#Blocking()
test1()
print('Done!')

